//
//  GCDViewController.m
//  ObjcGoNew
//
//  Created by 邢伟新 on 2021/4/15.
//

#import "GCDViewController.h"
#import <Masonry/Masonry.h>
#import "BarrierViewController.h"
#import "OtherGCDViewController.h"
#import "GroupGCDViewController.h"
#import "SemaphoreViewController.h"

typedef void(^TestBlock)(void);

@interface GCDViewController ()

@end

@implementation GCDViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.title = @"GCD";
    self.view.backgroundColor = [UIColor whiteColor];
    
    //栅栏按钮按钮
    UIButton *barrierButton = [UIButton buttonWithType:(UIButtonTypeCustom)];
    [barrierButton setTitle:@"跳转栅栏函数" forState:(UIControlStateNormal)];
    [barrierButton addTarget:self action:@selector(barrierAction:) forControlEvents:(UIControlEventTouchUpInside)];
    barrierButton.backgroundColor =[UIColor purpleColor];
    barrierButton.tag = 1001;
    [self.view addSubview:barrierButton];
    [barrierButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(15);
        make.right.mas_equalTo(-15);
        make.height.mas_equalTo(50);
        make.top.mas_equalTo(150);
    }];
    
    
    //GCD其他操作
    UIButton *afterButton = [UIButton buttonWithType:(UIButtonTypeCustom)];
    [afterButton setTitle:@"GCD其他用法" forState:(UIControlStateNormal)];
    afterButton.tag = 1002;
    [afterButton addTarget:self action:@selector(barrierAction:) forControlEvents:(UIControlEventTouchUpInside)];
    afterButton.backgroundColor =[UIColor purpleColor];
    [self.view addSubview:afterButton];
    [afterButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(15);
        make.right.mas_equalTo(-15);
        make.height.mas_equalTo(50);
        make.top.equalTo(barrierButton.mas_bottom).offset(15);
    }];
    
    
    //Group
    UIButton *GroupButton = [UIButton buttonWithType:(UIButtonTypeCustom)];
    [GroupButton setTitle:@"GCD-Group" forState:(UIControlStateNormal)];
    GroupButton.tag = 1003;
    [GroupButton addTarget:self action:@selector(barrierAction:) forControlEvents:(UIControlEventTouchUpInside)];
    GroupButton.backgroundColor =[UIColor purpleColor];
    [self.view addSubview:GroupButton];
    [GroupButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(15);
        make.right.mas_equalTo(-15);
        make.height.mas_equalTo(50);
        make.top.equalTo(afterButton.mas_bottom).offset(15);
    }];
    
    
    //信号量
    
    UIButton *semButton = [UIButton buttonWithType:(UIButtonTypeCustom)];
    [semButton setTitle:@"信号量" forState:(UIControlStateNormal)];
    [semButton addTarget:self action:@selector(barrierAction:) forControlEvents:(UIControlEventTouchUpInside)];
    semButton.backgroundColor =[UIColor purpleColor];
    semButton.tag = 1004;
    [self.view addSubview:semButton];
    [semButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(15);
        make.right.mas_equalTo(-15);
        make.height.mas_equalTo(50);
        make.top.mas_equalTo(GroupButton.mas_bottom).offset(15);
    }];
    
    
    
    
   [self gcdBlockCancel];
}

-(void)barrierAction:(UIButton *)btn{
    if (btn.tag == 1001) {
        BarrierViewController *b = [[BarrierViewController alloc]init];
        [self.navigationController pushViewController:b animated:YES];
        
    }
    else if (btn.tag == 1002){
        OtherGCDViewController *b = [[OtherGCDViewController alloc]init];
        [self.navigationController pushViewController:b animated:YES];
        
    }else if (btn.tag == 1003){
        
        GroupGCDViewController *gc = [[GroupGCDViewController alloc]init];
        [self.navigationController pushViewController:gc animated:YES];
        
    }else if (btn.tag == 1004){
        SemaphoreViewController *se = [[SemaphoreViewController alloc]init];
        [self.navigationController pushViewController:se animated:YES];
    }

    
}

//test10
-(void)test10{
    
//    NSLog(@"1---%@",[NSThread currentThread]);
//
//    dispatch_async(dispatch_get_global_queue(0, 0), ^{
//
//        for (int i = 0; i < 6; i++) {
//
//            [NSThread sleepForTimeInterval:2];
//
//            NSLog(@"%d----%@",i,[NSThread currentThread]);
//
//        }
//
//
//    });
    
    
        NSLog(@"1---%@",[NSThread currentThread]);
    //创建信号量
    dispatch_semaphore_t sem = dispatch_semaphore_create(1);
    
    //创建队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    //创建组
    dispatch_group_t group = dispatch_group_create();
       
    NSMutableArray *mutaArray = [NSMutableArray array];
 
       for (int i = 0; i < 6; i++) {
           dispatch_group_async(group, queue, ^{
               [NSThread sleepForTimeInterval:2];
                dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
                [mutaArray addObject:[NSNumber numberWithInt:i]];
                NSLog(@"%d----%@",i,[NSThread currentThread]);
                dispatch_semaphore_signal(sem);
           });
           
      }
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"数组为----%@---%@",mutaArray,[NSThread currentThread]);
    });
    
    

    
        
    
        
    
    
    
    
}



//串行队列同步添加任务
-(void)test1{
    
    //执行顺序为1 2 3 4 5 6,串行队列同步添加任务没有开启新线程,顺序执行
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
    NSLog(@"1 ------- %@",[NSThread currentThread]);
    
    dispatch_sync(queue, ^{
        NSLog(@"2 ------- %@",[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"3 ------- %@",[NSThread currentThread]);
    });

    dispatch_sync(queue, ^{
        NSLog(@"4 ------- %@",[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"5 ------- %@",[NSThread currentThread]);
    });
    
    NSLog(@"6 ------- %@",[NSThread currentThread]);
    
}


//并发队列,同步添加任务
-(void)test2{
    
    //执行顺序1 2 3 4 5 6,并发队列同步添加任务,不开启新的线程,顺序执行.
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    
    NSLog(@"1 ------- %@",[NSThread currentThread]);
    
    dispatch_sync(queue, ^{
        NSLog(@"2 ------- %@",[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"3 ------- %@",[NSThread currentThread]);
    });

    dispatch_sync(queue, ^{
        NSLog(@"4 ------- %@",[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"5 ------- %@",[NSThread currentThread]);
    });
    
    NSLog(@"6 ------- %@",[NSThread currentThread]);

}

//串行队列异步添加任务
-(void)test3{
    // 执行顺序 1 6 2 3 4 5,开启了一个新的线程,新线程中添加的任务顺序执行
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
    NSLog(@"1 ------- %@",[NSThread currentThread]);
    
    dispatch_async(queue, ^{
        NSLog(@"2 ------- %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"3 ------- %@",[NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"4 ------- %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"5 ------- %@",[NSThread currentThread]);
    });
    
    NSLog(@"6 ------- %@",[NSThread currentThread]);
    
}


//并发队列中,异步添加任务
-(void)test4{
    
    
    //执行顺序为1 6 2543,且2/3/4/5执行顺序不一定,开启了多条线程的.
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    
    NSLog(@"1 ------- %@",[NSThread currentThread]);
    
    dispatch_async(queue, ^{
        NSLog(@"2 ------- %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"3 ------- %@",[NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"4 ------- %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"5 ------- %@",[NSThread currentThread]);
    });
    
    NSLog(@"6 ------- %@",[NSThread currentThread]);
    
}


//线程死锁
//情况一:主队列中同步添加任务
-(void)test5{
    
    NSLog(@"1");
    
    dispatch_sync(dispatch_get_main_queue(), ^{
        
        NSLog(@"2");
    });
    
    
    NSLog(@"3");
    
}


//主队列中异步添加任务
-(void)test6{
    
    //执行顺序为 1 3 2,且都是在主线程中.
    
    
    NSLog(@"1 ------- %@",[NSThread currentThread]);
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
        NSLog(@"2 ------- %@",[NSThread currentThread]);
    });
    
    
    NSLog(@"3 ------- %@",[NSThread currentThread]);
    
}


//串行队列,先异步添加任务,再同步添加任务

-(void)test7{
    
    //1 4 2 崩溃
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
    NSLog(@"1 ------- %@",[NSThread currentThread]);
    
    dispatch_async(queue, ^{
        
        NSLog(@"2 ------- %@",[NSThread currentThread]);
        
        dispatch_sync(queue, ^{
            NSLog(@"3 ------- %@",[NSThread currentThread]);
        });
    });
    
    NSLog(@"4 ------- %@",[NSThread currentThread]);
}



//京东面试题
-(void)test8{
    
    
    //1.加了__block修饰则输出 test1
    //2.没加__block修饰则输出 test
    
    @autoreleasepool {
//       __block NSString *test = @"test";
        
        
        NSString *test = @"test";
        
        TestBlock block = ^{
         
            dispatch_queue_t queue = dispatch_queue_create("com.hello.xwx", DISPATCH_QUEUE_SERIAL);
            dispatch_sync(queue, ^{
                NSLog(@"%@",test);
            });
        };
        
        test = @"test1";
        
        block();
        
        
        
    }
    
}


//志东笔试题
-(void)test9{
    
    
    /*
     2021-04-15 15:08:44.848353+0800 ObjcGoNew[5106:273366] 1 ------- <NSThread: 0x6000037608c0>{number = 1, name = main}
     2021-04-15 15:08:44.848560+0800 ObjcGoNew[5106:273366] 3 ------- <NSThread: 0x6000037608c0>{number = 1, name = main}
     2021-04-15 15:08:44.848561+0800 ObjcGoNew[5106:273512] 2 ------- <NSThread: 0x600003724900>{number = 5, name = (null)}
     2021-04-15 15:08:44.848823+0800 ObjcGoNew[5106:273366] 4 ------- <NSThread: 0x6000037608c0>{number = 1, name = main}
     2021-04-15 15:08:44.848961+0800 ObjcGoNew[5106:273366] 5 ------- <NSThread: 0x6000037608c0>{number = 1, name = main}
     */
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
    NSLog(@"1 ------- %@",[NSThread currentThread]);
    
    dispatch_async(queue, ^{
        
        NSLog(@"2 ------- %@",[NSThread currentThread]);
        
    });
    
    NSLog(@"3 ------- %@",[NSThread currentThread]);
    
    dispatch_sync(queue, ^{
        NSLog(@"4 ------- %@",[NSThread currentThread]);
    });
    
    
    NSLog(@"5 ------- %@",[NSThread currentThread]);
    
}


//任务取消
-(void)gcdBlockCancel{
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_block_t block1 = dispatch_block_create(0, ^{
       
        NSLog(@"1-----%@",[NSThread currentThread]);
    });
    dispatch_block_t block2 = dispatch_block_create(0, ^{
        NSLog(@"2-----%@",[NSThread currentThread]);
    });
    dispatch_block_t block3 = dispatch_block_create(0, ^{
        NSLog(@"3-----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, block1);
    dispatch_async(queue, block2);
    dispatch_async(queue, block3);
    //取消任务3
    dispatch_block_cancel(block3);
    
}


@end
